#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Zhangcl
from django.utils.translation import ugettext as _
from django.forms import forms, ModelForm
from django.forms import ValidationError
from crm import models


def create_model_form(request,admin_class):
    '''动态生成model form'''
    def __new__(cls, *args, **kwargs):
        for field_name, field_obj in cls.base_fields.items():
            field_obj.widget.attrs['class'] = 'form-control'

            if not hasattr(admin_class, "is_add_form"):  # 判断是否是添加页面，不是就加disabled
                if field_name in admin_class.readonly_fields:
                    field_obj.widget.attrs['disabled'] = 'disabled'

            if hasattr(admin_class, "clean_%s" % field_name):
                field_clean_func = getattr(admin_class, "clean_%s" % field_name)
                setattr(cls, "clean_%s" % field_name, field_clean_func)
        return ModelForm.__new__(cls)

    def default_clean(self):
        '''给所有的form默认加一个clean验证'''
        print("---running default clean", admin_class)
        print("---running default clean", admin_class.readonly_fields)
        print("---obj instance", self.instance)
        error_list = []

        for field in admin_class.readonly_fields:
            field_val = getattr(self.instance, field)
            if hasattr(field_val, "select_related"):  # m2m
                m2m_objs = getattr(field_val, "select_related")().select_related()
                print(m2m_objs)
                m2m_vals = [i[0] for i in m2m_objs.values_list('id')]
                print(m2m_vals)
                set_m2m_vals = set(m2m_vals)
                set_m2m_vals_from_frontend = set([i.id for i in self.cleaned_data.get(field)])
                print("set_m2m:", set_m2m_vals, set_m2m_vals_from_frontend)
                if set_m2m_vals != set_m2m_vals_from_frontend:
                    error_list.append(ValidationError(
                        _('Field %(field)s is readonly'),
                        code='invalid',
                        params={'field': field, 'val': field_val}
                    ))
                    self.add_error(field, "readonly field")
                    continue
            field_val_from_frontend = self.cleaned_data.get(field)
            print("---field compare:", field, field_val, field_val_from_frontend)
            if field_val != field_val_from_frontend:
                error_list.append(ValidationError(
                    _('Field %(field)s is readonly,data should be %(val)s'),
                    code='invalid',
                    params={'field': field, 'val': field_val}
                ))

            if admin_class.readonly_table:
                raise ValidationError(
                    _('Table is readonly'),
                    code='invalid',
                )

            self.ValidationError = ValidationError
            response = admin_class.default_from_validation(self)  # 调用自己添加的验证
            if response:
                error_list.append(response)
            if error_list:
                raise ValidationError(error_list)

    class Meta:
        model = admin_class.model
        fields = "__all__"
        exclude = admin_class.modelform_exclude_fields
    attrs = {'Meta': Meta}
    _model_form_class = type("DynamicModelForm", (ModelForm,), attrs)
    setattr(_model_form_class, '__new__', __new__)
    setattr(_model_form_class, 'clean', default_clean)
    #  print("model form", _model_form_class.Meta.model)
    return _model_form_class